package edu.friday.service.impl;

import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysUser;
import edu.friday.model.vo.SysUserVo;
import edu.friday.repository.SysUserRepository;
import edu.friday.service.SysUserService;
import edu.friday.utils.BeanUtils;
import edu.friday.utils.StringUtils;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.Email;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import edu.friday.common.constant.UserConstants;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    SysUserRepository sysUserRepository;
    @Override
    public List<SysUser> selectUserList() {
        return sysUserRepository.findAll();
    }

    @Override
    public TableDataInfo selectUserByPage(SysUserVo sysUserVo, Pageable pageable) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyPropertiesIgnoreEmpty(sysUserVo, sysUser);
        sysUser.setDelFlag('0');

        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("userName",ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("phonenumber",ExampleMatcher.GenericPropertyMatchers.contains());


        Example<SysUser> example = Example.of(sysUser, exampleMatcher);
        Page<SysUser> page= sysUserRepository.findAll(example,pageable);
        return TableDataInfo.success(page.toList(),page.getTotalElements());

    }

    @Override
    public String checkUserNameUnique(String userName) {
        SysUser sysUser=new SysUser();
        sysUser.setUserName(userName);
        Example<SysUser> example = Example.of(sysUser);
        long count = sysUserRepository.count(example);
        if(count>0){
            return UserConstants.NOT_UNIQUE;
        }

        return UserConstants.UNIQUE;
    }

    @Override
    public String checkUserPhoneUnique(SysUserVo userVo) {
        SysUser sysUser=new SysUser();
        sysUser.setId(userVo.getId());
        if (userVo.getPhonenumber()==null){
            return UserConstants.UNIQUE;
        }
        sysUser.setPhonenumber(userVo.getPhonenumber());
        return checkUnique(sysUser);
    }

    @Override
    public String checkEmailUnique(SysUserVo userVo) {
        SysUser sysUser=new SysUser();
        sysUser.setId(userVo.getId());
        if (userVo.getEmail()==null){
            return UserConstants.UNIQUE;
        }
        sysUser.setEmail(userVo.getEmail());
        return checkUnique(sysUser);
    }



    private String checkUnique(SysUser sysUser) {
        Long id = sysUser.getId();
        if (StringUtils.isNull(id)) {
            id=1L;
        }
        sysUser.setId(null);
        Example<SysUser> example = Example.of(sysUser);
        if (sysUserRepository.count(example)>1) {
            return UserConstants.NOT_UNIQUE;
        }
        Optional<SysUser> optional = sysUserRepository.findOne(example);
        if (optional.isPresent()) {
            SysUser sysUser1 = optional.get();
            if(sysUser1.getId().equals(id)){
                return UserConstants.UNIQUE;
            }
            else {
                return UserConstants.NOT_UNIQUE;
            }
        }
        else {
            return UserConstants.UNIQUE;
        }
    }

    @Override
    @Transactional
    public int insertUser(SysUserVo user) {
        SysUser sysUser=new SysUser();
        BeanUtils.copyProperties(user,sysUser);
        sysUser.setDelFlag('0');
        sysUserRepository.save(sysUser);

        user.setId(sysUser.getId());
        insertUserRole(user);
        return 1;
    }


    @Transactional
    public int insertUserRole(SysUserVo user) {
        Long [] roles=user.getRoleIds();
        if(StringUtils.isNull(roles) || roles.length==0){
            return -1;
        }

        Long [] userIds=new Long[roles.length];
        for(int i=0;i<roles.length;i++){
            userIds[i]=user.getId();
        }
        return sysUserRepository.batchInserUserRole(roles,userIds);

    }


    @Override
    @Transactional
    public int deleteUserByIds(Long[] userIds) {
        return sysUserRepository.deleteUserByIds(userIds);
    }

    @Override
    @Transactional
    public int realDeleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            sysUserRepository.deleteById(userId);
        }
        return 1;
    }

    @Override
    @Transactional
    public int updateUser(SysUserVo user) {
        Long userId=user.getId();
        Optional<SysUser> optional = sysUserRepository.findById(userId);
        if(optional.isEmpty()){

            return 0;
        }


        SysUser sysUser=optional.get();
        BeanUtils.copyPropertiesIgnoreNull(user,sysUser);
        sysUserRepository.save(sysUser);

        if (user.getRoleIds()!=null){
            sysUserRepository.deleteUserRoleByIds(userId);
            insertUserRole(user);
        }

        if (null==sysUser.getId()) {
            return 0;
        }
        return 1;
    }

    @Override
    public SysUser selectUserById(Long userId) {
        SysUser sysUser=new SysUser();
        sysUser.setId(userId);
        sysUser.setDelFlag('0');
        return  sysUserRepository.findOne(Example.of(sysUser)).get();
    }

    @Override
    public SysUser selectUserByUserName(String username) {
        SysUser sysUser=new SysUser();
        sysUser.setUserName(username);
        Example<SysUser> example = Example.of(sysUser);
        Optional<SysUser> optional = sysUserRepository.findOne(example);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }


}
